﻿using LdtJudge.DataEngine.Model.DataModel.SysCommon;
using LdtJudge.DataEngine.Model.XMLConfigModel.SameNodeConfigModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;

namespace LdtDataEngin.ModuleDetail.BaseModule.MultiFack
{
    /// <summary>
    /// 要素信息推导核心要素
    /// </summary>
    public class MultiFactKernel : MultiFactBase
    {
        private LdtJudge.DataEngine.Common.CommHelp.GetSysCaseCause sysCaseCause = new LdtJudge.DataEngine.Common.CommHelp.GetSysCaseCause();

        public List<CaseCauseModel> Ms_caseCauseModeList { get; set; }
        /// <summary>
        ///构造函数
        /// </summary>
        public MultiFactKernel()
        {
        }

        public override string MultiFactHandleCommon(XmlNode template, Dictionary<Tuple<string, string>, XmlNode> personxml, List<SameNodeXml> sameNodeXmls, SameNodeHandleType nodeHandleType)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 当前案由的核心要素集合
        /// </summary>
        private List<CaseCauseModel> ListcaseCauses { get; set; }

        /// <summary>
        /// 生成核心要素对应的缺失要素
        /// </summary>
        /// <param name="template">节点模板</param>
        /// <param name="factxml">要素结果</param>
        /// <param name="isAddindex">是否添加序号</param>
        /// <returns></returns>
        public string MutiBuildKernelFact(XmlNode template, XmlNode factxml, bool isAddindex = false)
        {
            if (factxml != null && Ms_caseCauseModeList!= null && Ms_caseCauseModeList.Count > 0)
            {
                if (isAddindex)
                {
                    base.InsertAllNodeIndexNew(factxml, "");
                }
                string casecauseID = Ms_caseCauseModeList[0].CC_ID;
                //获取当前案由下的所有要素节点配置
                ListcaseCauses = sysCaseCause.GetList_FactElement(casecauseID).Where(ca => ca.CC_IsBasicElements == 1).ToList();
                if (ListcaseCauses.Count > 0)
                {//查询到当前的案由需要包含核心要素集合
                    XmlDocument resultXml = new XmlDocument();
                    resultXml.LoadXml(string.Format("<{0}></{0}>", template.ParentNode.Name));
                    XmlNode faNode = resultXml.CreateElement("事实要素");

                    resultXml.DocumentElement.AppendChild(faNode);
                    XmlNode factNode = factxml.SelectSingleNode("//事实要素[@要素类型='4']");

                    XmlAttribute factindex = resultXml.CreateAttribute("序号");
                    factindex.Value = Convert.ToInt32(factNode.Attributes["序号"]?.Value) + 1 + "";
                    faNode.Attributes.Append(factindex);

                    XmlAttribute facttype = resultXml.CreateAttribute("要素类型");
                    facttype.Value = "5";
                    faNode.Attributes.Append(facttype);
                    if (factNode != null && template != null)
                    {
                        LoopNode(template, factNode, faNode,new List<string>());
                    }
                    //去除空节点
                    //XmlDocument resultEscape=base.EscapeBlank(resultXml);
                    base.EscapeNodeIndexAndNoChild(resultXml);
                    XmlNode factnodeNew = (factxml as XmlDocument).ImportNode(faNode, true);
                    factxml.FirstChild.AppendChild(factnodeNew);
                    return resultXml.OuterXml;
                }
            }
            return string.Empty;
        }

        /// <summary>
        /// 进行遍历节点补充数据
        /// </summary>
        /// <param name="template">模板数据</param>
        /// <param name="dataNode">数据节点</param>
        /// <param name="resultNode">返回数据结果</param>
        private void LoopNode(XmlNode template, XmlNode dataNode, XmlNode resultNode,List<string> existDatas)
        {
            foreach (XmlNode tchildNode in template.ChildNodes)
            {
                SupplyNode(tchildNode, dataNode, resultNode, existDatas);
            }
        }

        /// <summary>
        /// 进行对节点的数据做缺失要素验证
        /// </summary>
        /// <param name="template">模板数据</param>
        /// <param name="dataNode">数据节点</param>
        /// <param name="resultNode">返回结果数据</param>
        private void SupplyNode(XmlNode template, XmlNode dataNode, XmlNode resultNode, List<string> exists)
        {

            string txmlpath = "/" + base.GetXmlPath(template);

            //如果当前节点不存在，且是核心要素，则需要创建节点
            List<XmlNode> childNodes = dataNode.SelectNodes(template.Name).Cast<XmlNode>().ToList();
            //获取包含核心要素
            bool isContain = ListcaseCauses.Any(x => x.XmlPath == txmlpath);
            if (childNodes.Count == 0 && isContain)
            {
                //if (template.ParentNode.Name == "事实要素")
                //{
                XmlNode node = resultNode.OwnerDocument.CreateElement(template.Name);
                resultNode.AppendChild(node);
                //获取对应的属性
                this.SupplyAttr(template, txmlpath, null, node, exists);
                this.LoopNode(template, dataNode, node, exists);
                //}
            }
            else
            {
                foreach (var child in childNodes)
                {
                    XmlNode node = resultNode.OwnerDocument.CreateElement(template.Name);
                    resultNode.AppendChild(node);
                    //获取对应的属性
                    this.SupplyAttr(template, txmlpath, child, node, exists);
                    this.LoopNode(template, child, node, exists);
                }
            }

        }

        /// <summary>
        /// 进行属性内容补充
        /// </summary>
        /// <param name="template">节点模板</param>
        /// <param name="txmlpath">节点xmlpath</param>
        /// <param name="dataNode">数据节点</param>
        /// <param name="resultNode">返回的数据节点</param>
        private void SupplyAttr(XmlNode template, string txmlpath, XmlNode dataNode, XmlNode resultNode, List<string> existDatas)
        {
            if (dataNode != null)
            {
                if (resultNode.Attributes.GetNamedItem("序号") == null)
                {
                    XmlAttribute attrxuhao = resultNode.OwnerDocument.CreateAttribute("序号");
                    attrxuhao.Value = dataNode.Attributes["序号"]?.Value;
                    if (string.IsNullOrWhiteSpace(attrxuhao.Value))
                    {
                        attrxuhao.Value = "0";
                    }
                    resultNode.Attributes.Append(attrxuhao);
                }
            }
            else
            {
                if (resultNode.Attributes.GetNamedItem("序号") == null)
                {
                    XmlAttribute attrxuhao = resultNode.OwnerDocument.CreateAttribute("序号");
                    attrxuhao.Value = "0";
                    resultNode.Attributes.Append(attrxuhao);
                }

            }
            //判断节点对应的属性是否为核心要素
            foreach (XmlAttribute tchildattr in template.Attributes)
            {
                //获取包含核心要素
                string txmlpathattr = txmlpath + "/@" + tchildattr.Name;
                bool isContainAttr = ListcaseCauses.Any(x => x.XmlPath == txmlpathattr);
                if (isContainAttr)
                {
                    bool isConattr = false;
                    if (dataNode != null)
                    {
                        isConattr = dataNode.Attributes.Cast<XmlAttribute>().Any(a => a.Name == tchildattr.Name);
                    }
                    if (!isConattr)
                    {
                        if(!existDatas.Contains(txmlpathattr))
                        {
                            XmlAttribute attributet = resultNode.OwnerDocument.CreateAttribute(tchildattr.Name);
                            resultNode.Attributes.Append(attributet);
                        }
                    }
                    else
                    {
                        if(!existDatas.Contains(txmlpathattr))
                            existDatas.Add(txmlpathattr);
                        var removeNode = resultNode.OwnerDocument.SelectNodes(txmlpath);
                        if(removeNode!=null)
                        {
                            for (int i = 0; i < removeNode.Count; i++)
                            {
                                if(removeNode[i].Attributes[tchildattr.Name]!=null)
                                {
                                    removeNode[i].Attributes[tchildattr.Name].RemoveAll();
                                }
                            }
                        }
                    }
                }
            }


        }
    }
}
